//
//  ViewController.m
//  YHNullDemo
//
//  Created by yanHu on 2022/11/1.
//❗️❗️❗️❗️❗️❗️

#import "ViewController.h"
#import "YHDictionary.h"
@import testFramework;

@interface ViewController ()

@property (nonatomic, strong) YHDictionary *yhString;

@property (nonatomic, strong) NSArray<NSString *> *methods;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.yhString = YHDictionary.new;
    NSLog(@"self.yhString - %p", self.yhString);
    [self performSelector:@selector(objectForKey)];
    TestView *view = [TestView new];
//    NSNull *null = [NSNull new];
    
    //    字符串
//    NSString *nullString = (NSString *)null;
    NSString *nullString = (NSString *)self;
    [nullString substringToIndex:2];
    
    //    字典
//    NSDictionary *nullDictonary = (NSDictionary *)null;
    NSDictionary *nullDictonary = (NSDictionary *)self;
    [nullDictonary objectForKey:@"123"];
    
    //    数组
//    NSArray *nullArray = (NSArray *)null;
    NSArray *nullArray = (NSArray *)self;
    [nullArray objectAtIndex:2];
    
    //    NSNumber
//    NSNumber *nullNumber = (NSNumber *)null;
    NSNumber *nullNumber = (NSNumber *)self;
    [nullNumber stringValue];
    
    //    NSDate
//    NSDate *nullDate = (NSDate *)null;
    NSDate *nullDate = (NSDate *)self;
    [nullDate description];
    
    //    NSData
//    NSData *nullData = (NSData *)null;
    NSData *nullData = (NSData *)self;
    [nullData subdataWithRange:NSMakeRange(0, 3)];
    
}

#pragma mark - 消息机制的第一步 消息处理机制 判断是否能接受SEL
/**
 对象：在接受到无法解读的消息的时候 首先会调用所属类的类方法

 @param sel 传递进入的方法
 @return 如果YES则能接受消息 NO不能接受消息 进入第二步
 */
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSLog(@"resolveInstanceMethod: - ");
//    if ([self respondsToSelector:sel]) {
//        return YES;
//    }
    return [super resolveInstanceMethod:sel];
}

#pragma mark - 消息机制的第二步 消息转发机制

/**
 转发SEL去对象内部的其他可以响应的对象

 @param aSelector 需要被响应的方法SEL
 @return 返回一个可以被响应的该SEL的对象 如果返回self或者nil,则说明没有可以响应的目标 则进入第三步
 */
- (id)forwardingTargetForSelector:(SEL)aSelector {
    NSLog(@"forwardingTargetForSelector: - ");
//    if ([self.methods containsObject:NSStringFromSelector(aSelector)]) {
//        return self.yhString;
//    }
    return [super forwardingTargetForSelector:aSelector];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSLog(@"methodSignatureForSelector: - ");
    if ([self.methods containsObject:NSStringFromSelector(aSelector)]) {
        return [self.yhString methodSignatureForSelector:aSelector];
    }
    return [super methodSignatureForSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    NSLog(@"forwardInvocation: - ");
    SEL sel = anInvocation.selector;
    NSLog(@"brfore - %@", anInvocation.target);
    //判断备用对象是否可以响应传递进来等待响应的SEL
    if ([self.yhString respondsToSelector:sel]) {
        [anInvocation invokeWithTarget:self.yhString];
        NSLog(@"after - %p", anInvocation.target);
    }else{
//    如果备用对象不能响应 则抛出异常
        [self doesNotRecognizeSelector:sel];
    }
    
}

- (NSArray<NSString *> *)methods {
    if (_methods == nil) {
        _methods = @[@"objectForKey", @"substringToIndex:", @"objectForKey:", @"objectAtIndex:", @"stringValue", @"description", @"subdataWithRange:"];
    }
    return _methods;
}

@end
